﻿using System;
using System.Collections.Generic;
using NHibernate.Mapping.ByCode.Conformist;
using Xenta.Enums;

namespace Xenta.Entities
{
    /// <summary>
    /// Exposes the entity interface.
    /// </summary>
    /// <remarks>
    /// The core part of the framework. The entity 
    /// usually is a projection of the database table.
    /// </remarks>
    public interface IEntity : IDisclosable
    {
        /// <summary>
        /// Gets or sets the entity identifier.
        /// </summary>
        int EntityID
        {
            get;
            set;
        }
    }

    /// <summary>
    /// Represents the entity.
    /// </summary>
    public abstract class Entity : IEntity
    { 
        #region Properties

        /// <summary>
        /// Gets or sets the entity identifier.
        /// </summary>
        public virtual int EntityID
        {
            get;
            set;
        }

        #endregion

        #region Methods

        /// <summary>
        /// Discloses the entity.
        /// </summary>
        /// <param name="level">The disclosure level.</param>
        /// <param name="options">The disclosure options.</param>
        /// <returns>The object.</returns>
        public virtual object Disclose(DisclosureLevel level, IDictionary<String, String> options)
        {
            var obj = new Dictionary<String, Object>();
            Disclose(obj, level, options);
            return obj;
        }

        #endregion

        #region Utilities

        /// <summary>
        /// Discloses the entity by filling the dictionary.
        /// </summary>
        /// <param name="obj">The object to fill.</param>
        /// <param name="level">The disclosure level.</param>
        /// <param name="options">The disclosure options.</param>
        protected virtual void Disclose(IDictionary<String, Object> obj, 
            DisclosureLevel level, 
            IDictionary<String, String> options)
        {
            if(level >= DisclosureLevel.Primary)
                obj["EntityID"] = EntityID;
        }

        #endregion
    }

    /// <summary>
    /// The entity NHibernate mapping.
    /// </summary>
    public abstract class EntityMapping<TEntity> : ClassMapping<TEntity> 
        where TEntity : Entity
    {
    }

    /// <summary>
    /// The entity NHibernate mapping.
    /// </summary>
    public abstract class SubEntityMapping<TEntity> : SubclassMapping<TEntity>
        where TEntity : Entity
    {
    }

    /// <summary>
    /// The entity NHibernate mapping.
    /// </summary>
    public abstract class JoinedEntityMapping<TEntity> : JoinedSubclassMapping<TEntity>
        where TEntity : Entity
    {
    }
}
